package com.topvision.myviewtest.gscview;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * @author lucy
 * @date 2018-11-27 16:07
 * @description //TODO
 */

public class SearchPathView extends View {
    private static final long DEFAULT_DURATION = 1000;
    private Paint mPaint;
    private Path mPathSearch, mPathCircle;
    private PathMeasure mPathMeasure;
    private int mViewWidth;
    private int mViewHeight;
    private ValueAnimator mStartAnimator, mSearchAnimator, mEndAnimator;
    private ValueAnimator.AnimatorUpdateListener mUpdateListener;
    private Animator.AnimatorListener mAnimatorListener;
    private float mAnimatedValue;
    private State mCurrentState = State.IDLE;
    private Handler mAnimatorHandler;
    private boolean isOver;
    private int count;

    enum State {
        IDLE,
        START,
        SEARCH,
        END
    }

    public SearchPathView(Context context) {
        this(context, null);
    }

    public SearchPathView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SearchPathView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        initPaint();

        initPath();

        initHandler();

        initLisenter();

        initAnimator();

        // 进入开始动画
        mCurrentState = State.START;
        mStartAnimator.start();
    }

    private void initLisenter() {
        mUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAnimatedValue = (float) animation.getAnimatedValue();
                invalidate();
            }
        };

        mAnimatorListener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                // 动画结束 getHandle发消息通知动画状态更新
                mAnimatorHandler.sendEmptyMessage(0);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        };
    }

    private void initHandler() {
        mAnimatorHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (mCurrentState) {
                    case START:
                        // 从开始动画转换好搜索动画
                        isOver = false;
                        mCurrentState = State.SEARCH;
                        mStartAnimator.removeAllListeners();
                        mSearchAnimator.start();
                        break;
                    case SEARCH:
                        if (!isOver) {  // 如果搜索未结束 则继续执行搜索动画
                            mSearchAnimator.start();
                            Log.e("Update", "RESTART");

                            count++;
                            if (count > 2) {       // count大于2则进入结束状态
                                isOver = true;
                            }
                        } else {        // 如果搜索已经结束 则进入结束动画
                            mCurrentState = State.END;
                            mEndAnimator.start();
                        }
                        break;
                    case END:
                        // 从结束动画转变为无状态
                        mCurrentState = State.IDLE;
                        break;
                    default:
                        break;
                }
            }
        };
    }

    private void initAnimator() {
        mStartAnimator = ValueAnimator.ofFloat(0, 1).setDuration(DEFAULT_DURATION);
        mSearchAnimator = ValueAnimator.ofFloat(0, 1).setDuration(DEFAULT_DURATION);
        mEndAnimator = ValueAnimator.ofFloat(1, 0).setDuration(DEFAULT_DURATION);

        mStartAnimator.addUpdateListener(mUpdateListener);
        mSearchAnimator.addUpdateListener(mUpdateListener);
        mEndAnimator.addUpdateListener(mUpdateListener);

        mStartAnimator.addListener(mAnimatorListener);
        mSearchAnimator.addListener(mAnimatorListener);
        mEndAnimator.addListener(mAnimatorListener);
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(5);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setAntiAlias(true);
    }

    private void initPath() {
        mPathSearch = new Path();
        mPathCircle = new Path();

        mPathMeasure = new PathMeasure();

        // 放大镜圆圈
        RectF oval1 = new RectF(-50, -50, 50, 50);
        // 注意,不要到360度,否则内部会自动优化,测量不能取到需要的数值
        mPathSearch.addArc(oval1, 45, 359.9f);

        // 外部圆圈
        RectF oval2 = new RectF(-100, -100, 100, 100);
        mPathCircle.addArc(oval2, 45, -359.9f);

        float[] pos = new float[2];
        mPathMeasure.setPath(mPathCircle, false);
        mPathMeasure.getPosTan(0, pos, null);
        // 放大镜把手
        mPathSearch.lineTo(pos[0], pos[1]);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mViewWidth = w;
        mViewHeight = h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawSearch(canvas);
    }

    private void drawSearch(Canvas canvas) {
        // 坐标轴移到中间
        canvas.translate(mViewWidth / 2, mViewHeight / 2);
        canvas.drawColor(Color.parseColor("#0082D7"));
        switch (mCurrentState) {
            case IDLE:
                canvas.drawPath(mPathSearch, mPaint);
                break;
            case START:
                mPathMeasure.setPath(mPathSearch, false);
                Path dst = new Path();
                mPathMeasure.getSegment(mPathMeasure.getLength() * mAnimatedValue, mPathMeasure.getLength(), dst, true);
                canvas.drawPath(dst, mPaint);
                break;
            case SEARCH:
                mPathMeasure.setPath(mPathCircle, false);
                Path dst2 = new Path();
                float stop = mPathMeasure.getLength() * mAnimatedValue;
                float start = (float) (stop - ((0.5 - Math.abs(mAnimatedValue - 0.5)) * 200f));
                mPathMeasure.getSegment(start, stop, dst2, true);
                canvas.drawPath(dst2, mPaint);
                break;
            case END:
                mPathMeasure.setPath(mPathSearch, false);
                Path dst3 = new Path();
                mPathMeasure.getSegment(mPathMeasure.getLength() * mAnimatedValue, mPathMeasure.getLength(), dst3, true);
                canvas.drawPath(dst3, mPaint);
                break;
            default:
                break;
        }
    }
}
